/* * * * M A P V I S I O N   L I C E N S E  *****************************************************************
 *
 * This MapVision software is © Filip Zavadil 2013. It is licensed under the LGPL license.
 * This MapVision software dynamically links to unmodified Qt5 Library.
 *
 * The Qt5 Library is © 2013 Qt® and/or its subsidiary(-ies), and is licensed under the
 * GNU Lesser General Public License version 2.1 with Qt® LGPL exception version 1.1.
 * Qt5 library is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
 * Qt5 library is provided “AS IS”, without WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * As an additional permission to the GNU Lesser General Public License version 2.1, the object
 * code form of a “work that uses the Library” may incorporate material from a header file that is
 * part of the Library. You may distribute such object code under terms of your choice,
 * provided that: (i) the header files of the Library have not been modified; and (ii)
 * the incorporated material is limited to numerical parameters, data structure layouts, accessors,
 * macros, inline functions and templates; and (iii) you comply with the terms of Section 6 of the
 * GNU Lesser General Public License version 2.1.
 *
 * Moreover, you may apply this exception to a modified version of the Library, provided that such
 * modification does not involve copying material from the Library into the modified Library’s header
 * files unless such material is limited to (i) numerical parameters; (ii) data structure layouts;
 * (iii) accessors; and (iv) small macros, templates and inline functions of five lines or less in length.
 *
 * Furthermore, you are not required to apply this additional permission to a modified version of the Library.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this package;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

 * The source code for Qt 5.X SDK is available from Qt Project here:
 * http://download.qt-project.org/official_releases/qtcreator/2.7/2.7.0/qt-creator-2.7.0-src.zip.
 *
 * ****************************** M A P V I S I O N    S O F T W A R E  ************************************
 *
 * Author:       Filip Zavadil
 * Description:  Software for displaying and exporting map tiles.
 * The sources and executables of MapVision software are available:
 *    - from project hosting on CodePlex.com :   http://mapvision.codeplex.com
 *    - from GIT repositories on Gitorious.org:  https://gitorious.org/mapvision
 * Visit MapVision fanpage on Facebook.com:      https://www.facebook.com/pages/Mapvision/631827753513935
 *
 * *********************************************************************************************************
*/

#include "layertileslocal.h"
#include <QtConcurrent/QtConcurrentRun>


LayerTILESlocal::LayerTILESlocal(QMainWindow *mainWindow_) : Layer(mainWindow_)
{

    openDialog = new DialogLayerTILESlocal(mainWindow_,this);
    if (openDialog->exec()) {
        this->init();

    } else {
        this->deleteLater();
    }
}



LayerTILESlocal::LayerTILESlocal(QMainWindow *mainWindow_, Layer::layerType type_, QString name_, QString source_, QPointF lonlat_, int zoom_, int zValue_, int opacity_)
    : Layer(mainWindow_)
{
    setLayerType(type_);
    setLayerName(name_);
    setOrigin(lonlat_,zoom_);
    setOpacity(double(opacity_)/100.0);
    setSource(source_);
    setZvalue(zValue_);
    this->init();

}

void LayerTILESlocal::init()
{
    getMapScene()->addItem(layerGroup);

    connect(this,SIGNAL(tileIsReady(QString,QPoint,int,QImage)),
            this,SLOT(tileIsRendering(QString,QPoint,int,QImage)));

    connect(this,SIGNAL(tileToload(QString,QPoint,int)),
            this,SLOT(tileIsLoad(QString,QPoint,int)));

    // insert item to layer list
    QListWidgetItem *item = new QListWidgetItem(this->getLayerName());
    item->setIcon(QIcon("images/buttons/tilesLocal.svg"));
    item->setCheckState(Qt::Checked);
    item->setData(Qt::UserRole,getId());
    getListWidget()->insertItem(getZvalue(),item);

    setZvalue(this->getListWidget()->count()-1);
    layerGroup->setZValue(getZvalue());

    emit sendMessage("<code>"+tr("Layer ")+this->getLayerName()+tr(" was loaded!")+"</code><br>"  );

    getMapView()->refresh();

}

QImage LayerTILESlocal::getTile(QPoint tile, int zoom)
{
    QString tilePath = getSource()+"/"+QString::number(zoom)+"/"+QString::number(tile.x())+"/"+QString::number(tile.y())+".png";
    return QImage(tilePath);
}

void LayerTILESlocal::mapRectChanged(QRect rect, int zoom)
{
    if (isRendering())
    {
        int cache=0;

        for (int x=rect.left()-cache;x<=rect.right()+cache;x++)
        {
            for (int y=rect.bottom()-cache;y<=rect.top()+cache;y++)
            {
                QString tilePath = getSource()+"/"+QString::number(zoom)+"/"+QString::number(x)+"/"+QString::number(y)+".png";

                //if (!tiles.contains(tilePath))
                {
                    QPoint position = zavaProj.pointForTile(QPoint(x,y),zoom);

                    if (!sources.contains(tilePath)){
                        setTilesToLoad(1);
                        sources << tilePath;
                        if (renderingType == CONCURRENT){
                            QtConcurrent::run(this,&LayerTILESlocal::tileIsLoadingConCurent, tilePath, position,zoom);
                        } else if (renderingType == CURRENT){
                            tileIsLoadingConCurent(tilePath,position,zoom);
                        } else {
                            if (rect.width()>6) QtConcurrent::run(this,&LayerTILESlocal::tileIsLoadingConCurent, tilePath, position,zoom);
                            else tileIsLoadingConCurent(tilePath,position,zoom);
                        }


                    }

                }
            }
        }
    }
}


void LayerTILESlocal::tileIsLoadingConCurent(QString source, QPoint pos, int zoom_)
{
    emit tileToload(source,pos,zoom_);
}

void LayerTILESlocal::tileIsRendering(QString source,QPoint pos, int zoom_ ,QImage img)
{
    if (zoom_!=getMapView()->getZoom()){return;}
    QGraphicsPixmapItem * tile = new QGraphicsPixmapItem(QPixmap::fromImage(img));
    tile->moveBy(pos.x(),pos.y());
    tile->setData(Qt::UserRole,getLayerName());
    layerGroup->addToGroup(tile);
    items.insert(source,tile);
    setTilesToLoad(-1);

}

void LayerTILESlocal::tileIsLoad(QString source, QPoint pos , int zoom_)
{
    if (zoom_!=getMapView()->getZoom()){return;}
    QImage tile(source);
    if (tile.isNull()|| tile.size()!=QSize(256,256)){
        setTilesToLoad(-1);
        return;
    }
    emit tileIsReady(source,pos,zoom_,tile);

}
